﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Text.RegularExpressions;
using System.IO;
namespace GradeMerge
{
    public partial class Form1 : Form
    {
        private Dictionary<string,double> _targetDictionary;
        public Dictionary<string, double> TargetDictionary
        {
          get 
          {
              if (_targetDictionary == null)
                  _targetDictionary = BuildTargetDictionary();
              return _targetDictionary; }
          set { _targetDictionary = value; }
        }

        private Dictionary<string, double> _sourceDictionary;
        public Dictionary<string, double> SourceDictionary
        {
            get 
            {
                if (_sourceDictionary == null)
                    _sourceDictionary = BuildSourceDictionary();
                return _sourceDictionary; }
            set { _sourceDictionary = value; }
        }

        private string _targetFile;
        public string TargetFile
        {
            get { return _targetFile; }
            set { _targetFile = value; }
        }

        private string _sourceFile;
        public string SourceFile
        {
            get { return _sourceFile; }
            set { _sourceFile = value; }
        }

        private double _pointsPossible = -1;
        public double PointsPossible
        {
            get 
            {
                if (_pointsPossible < 0)
                {
                    Match match = new Regex(@"Pts: ([0-9]+)").Match(dgvTarget.SelectedColumns[0].HeaderText);
                        if (match.Captures.Count > 0)
                            Double.TryParse(match.Captures[0].Value.Replace("Pts: ", string.Empty), out _pointsPossible);
                        while (_pointsPossible == -1)
                        {
                            frmPoints frm = new frmPoints(null);
                            if (frm.ShowDialog(this) == DialogResult.OK)
                                _pointsPossible = frm.Points;
                            else
                                break;
                        }
                }
                return _pointsPossible;
            }
            set { _pointsPossible = value; }
        }

        private int _selectedSourceColumnIndex;
        public int SelectedSourceColumnIndex
        {
            get { return _selectedSourceColumnIndex; }
            set { _selectedSourceColumnIndex = value; }
        }

        private int _selectedTargetColumnIndex;
        public int SelectedTargetColumnIndex
        {
            get { return _selectedTargetColumnIndex; }
            set { _selectedTargetColumnIndex = value; }
        }

        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            DoResize();
            ShowOpenDialogs();
        }

        private void openToolStripMenuItem_Click(object sender, EventArgs e)
        {
            ShowOpenDialogs();
        }

        private void ShowOpenDialogs()
        {
            ofdOpen.Title = "Select Blackboard CSV File";
            if (ofdOpen.ShowDialog(this) == DialogResult.OK)
            {
                TargetFile = ofdOpen.FileName;

                ofdOpen.Title = "Select MathZone CSV File";
                if (ofdOpen.ShowDialog(this) == DialogResult.OK)
                {
                    SourceFile = ofdOpen.FileName;

                    PopulateInterface();
                }
            }
        }

        private void PopulateInterface()
        {
            BuildTable(TargetFile, dgvTarget);
            BuildTable(SourceFile, dgvSource);
        }

        private void BuildTable(string fileName, DataGridView grid)
        {
            using (CSVReader csv = new CSVReader(fileName))
            {
                string[] fields;

                string[] colNames = csv.GetCSVLine();
                foreach (string colName in colNames)
                {
                    DataGridViewColumn col = new DataGridViewColumn(new DataGridViewTextBoxCell());
                    col.SortMode = DataGridViewColumnSortMode.NotSortable;
                    col.HeaderCell.Value = colName;
                    grid.Columns.Add(col);
                }

                while ((fields = csv.GetCSVLine()) != null)
                {
                    if (fields.Length != 0) 
                        grid.Rows.Add(fields);
                }
            }
        }

        private Dictionary<string,double> BuildTargetDictionary()
        {
            Dictionary<string, double> dict = new Dictionary<string, double>();
            foreach (DataGridViewRow row in dgvTarget.Rows)
                dict.Add(row.Cells[0].Value.ToString().ToLower(), 0);

            return dict;
        }

        private Dictionary<string, double> BuildSourceDictionary()
        {
            Dictionary<string, double> dict = new Dictionary<string, double>();
            foreach (DataGridViewRow row in dgvSource.Rows)
            {
                if (row.Cells[0].Value != null && row.Cells[1].Value != null)
                {
                    double totalValue = 0;
                    foreach (DataGridViewColumn col in dgvSource.SelectedColumns)
                            totalValue += GetDoubleValue(row.Cells[col.Index].FormattedValue);

                    dict.Add(
                        BuildSourceName(row.Cells[0].FormattedValue, row.Cells[1].FormattedValue)
                    ,   totalValue / dgvSource.SelectedColumns.Count);

                }
            }

            return dict;
        }

        private string BuildSourceName(object lastName, object firstName)
        {
            return String.Format("{0}, {1}", lastName, firstName).ToLower();
        }

        private double GetDoubleValue(object colValue)
        {
            double ret = 0;
            if (colValue != null)
                double.TryParse(colValue.ToString().Replace("%", string.Empty), out ret);

            return ret;
        }


        private void Form1_Resize(object sender, EventArgs e)
        {
            DoResize();
        }

        private void DoResize()
        {
            dgvSource.Width = this.Width / 2 - 5;
            dgvTarget.Width = this.Width / 2 - 5;
        }



        private void mergeToolStripMenuItem_Click(object sender, EventArgs e)
        {
            foreach (DataGridViewColumn col in dgvSource.SelectedColumns)
                if (col.Index < 3) col.Selected = false;

            if (dgvTarget.SelectedColumns.Count > 0)
            {
                if (dgvSource.SelectedColumns.Count > 0)
                {
                    string[] targetKeys = new string[TargetDictionary.Keys.Count];
                    TargetDictionary.Keys.CopyTo(targetKeys,0);
                    foreach (string key in targetKeys)
                    {
                        string sourceKey = GetSourceKey(key);
                        if (SourceDictionary.ContainsKey(sourceKey))
                        {
                            TargetDictionary[key] = Math.Ceiling((SourceDictionary[sourceKey] / 100) * PointsPossible);
                        }
                    }

                    if (SaveTargetCSV())
                        CleanExistingValues();
                }
                else
                {
                    MessageBox.Show("You must select a source column!");
                }
            }
            else
            {
                MessageBox.Show("You must select a target column!");
            }

        }

        private void CleanExistingValues()
        {
            TargetDictionary = null;
            SourceDictionary = null;
            PointsPossible = -1;
        }

        private bool SaveTargetCSV()
        {
            if (sfdSave.ShowDialog(this) == DialogResult.OK)
            {
                using (TextWriter writer = new StreamWriter(sfdSave.FileName))
                {
                    WriteFile(writer);
                }

                MessageBox.Show(String.Format("Merged file Successfully Saved to '{0}'", sfdSave.FileName));

                return true;
            }

            return false;
        }

        private void WriteFile(TextWriter writer)
        {
            WriteFileHeader(writer);

            WriteFileBody(writer);
        }

        private void WriteFileBody(TextWriter writer)
        {
            foreach (KeyValuePair<string, double> kvp in TargetDictionary)
            {
                writer.WriteLine(
                    String.Format("\"{0}\",{1}"
                    , kvp.Key
                    , kvp.Value));
            }
        }

        private void WriteFileHeader(TextWriter writer)
        {
            writer.WriteLine(
                String.Format("\"{0}\",{1}"
                , dgvTarget.Columns[0].HeaderText
                , dgvTarget.SelectedColumns[0].HeaderText));
        }

        private string GetSourceKey(string key)
        {
            foreach(string sourceKey in SourceDictionary.Keys)
                if (key.StartsWith(sourceKey)) 
                    return sourceKey;

            return string.Empty;
        }

        private void exitToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Application.Exit();
        }

     
    }
}
